package com.iwomy.secureplat.platform.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.iwomy.secureplat.common.log.annotation.ReckonTime;
import com.iwomy.secureplat.platform.constant.RedisConstants;
import com.iwomy.secureplat.platform.constant.RedisExpirationTime;
import com.iwomy.secureplat.platform.dto.SensorTransmissionDataDto;
import com.iwomy.secureplat.platform.entity.BasicDeviceEntity;
import com.iwomy.secureplat.platform.service.BasicDeviceService;
import com.iwomy.secureplat.platform.service.HistoricalDataService;
import com.iwomy.secureplat.platform.service.RealTimeDataService;
import com.iwomy.secureplat.platform.transmission.entity.SensorTransmissionData;
import com.iwomy.secureplat.platform.transmission.entity.SensorTransmissionDataDetails;
import com.iwomy.secureplat.platform.utils.RedisClient;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 报警类型
 *
 * @author pig
 * @date 2023-12-22 19:11:50
 */
@Service
public class RealTimeDataServiceImpl implements RealTimeDataService {
	@Resource
	private MongoTemplate mongoTemplate;

	@Resource
	private BasicDeviceService deviceService;

	@Resource
	private HistoricalDataService historicalDataService;

	@Resource
	private RedisClient redisClient;

	@Override
	@ReckonTime
	public SensorTransmissionData getRedisByImei(String imei) {
		String key = RedisConstants.REDIS_KEY_DEVICE_REALTIME_DATA + imei;
		return redisClient.get(key, SensorTransmissionData.class);
	}

	@Override
	public SensorTransmissionData getOneByImei(String imei) {
		Query query = new Query(Criteria
				.where("deviceUniqueId").is(imei))
				.with(Sort.by(Sort.Direction.DESC, "receptionTime"))
				.limit(1);
		SensorTransmissionData one = mongoTemplate.findOne(query, SensorTransmissionData.class);
		return one;
	}

	@Override
	public Page page(Page page, SensorTransmissionDataDto sensorTransmissionDataDto) {
		Criteria criteria = Criteria
				.where("deviceUniqueId").is(sensorTransmissionDataDto.getImei());

		LocalDateTime[] createTime = sensorTransmissionDataDto.getCreateTime();
		if (ObjectUtil.isNotEmpty(createTime)) {
			criteria.andOperator(
					Criteria.where("receptionTime").gte(createTime[0]),
					Criteria.where("receptionTime").lte(createTime[1])
			);
		}
		if (ObjectUtil.isNotEmpty(sensorTransmissionDataDto.getAlarmEventTypeCode())) {
			criteria.and("alarmInfo").is(sensorTransmissionDataDto.getAlarmEventTypeCode());
		}
		if (ObjectUtil.isNotEmpty(sensorTransmissionDataDto.getAlarmEventTypeName())) {
			criteria.and("alarmEvenName").is(sensorTransmissionDataDto.getAlarmEventTypeName());
		}

		Pageable pageable = PageRequest.of((int) page.getCurrent() - 1, (int) page.getSize());

		Query query = new Query(criteria);
//				.skip((page.getCurrent() - 1) * page.getSize())  // 计算跳过的记录数
//				.limit((int) page.getSize());
		long totalCount = mongoTemplate.count(query, SensorTransmissionData.class);
		query.with(Sort.by(Sort.Direction.DESC, "receptionTime"));

		if (ObjectUtil.isNotEmpty(sensorTransmissionDataDto.getRange())) {
			Historicalrange(page, sensorTransmissionDataDto, query, createTime,totalCount);
		} else {
			List<SensorTransmissionData> sensorTransmissionData = mongoTemplate.find(query.with(pageable), SensorTransmissionData.class);
			page.setRecords(sensorTransmissionData);
			page.setTotal(totalCount);
		}
		return page;
	}

	@Override
	public JSONObject attributeCurve(SensorTransmissionDataDto sensorTransmissionDataDto) {

		List<SensorTransmissionData> list = page(new Page(), sensorTransmissionDataDto).getRecords();
		if (ObjectUtil.isEmpty(list)) return null;

		List x = new LinkedList();
		List y = new LinkedList();

		for (SensorTransmissionData transmissionData : list) {

			List<SensorTransmissionDataDetails> sensorTransmissionDataDetailsList = transmissionData.getSensorTransmissionDataDetailsList();
			x.add(transmissionData.getReceptionTime());
			if (ObjectUtil.isEmpty(sensorTransmissionDataDetailsList)) {
				y.add(0);
				continue;
			}
			List<SensorTransmissionDataDetails> collect = sensorTransmissionDataDetailsList.stream()
					.filter(i -> sensorTransmissionDataDto.getGasTypeIdAndUnit().equals(i.getGasTypeIdAndUnit())).collect(Collectors.toList());
			if (ObjectUtil.isEmpty(collect)) {
				y.add(0);
				continue;
			}
			SensorTransmissionDataDetails sensorTransmissionDataDetails = collect.get(0);
			y.add(sensorTransmissionDataDetails.getSensorVal());

		}
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("x", x);
		jsonObject.put("y", y);


		return jsonObject;
	}

	//查询历史数据列表
	private Page Historicalrange(Page page, SensorTransmissionDataDto sensorTransmissionDataDto, Query query, LocalDateTime[] createTime,long totalCount) {
		List<SensorTransmissionData> result = mongoTemplate.find(query, SensorTransmissionData.class);
		BasicDeviceEntity deviceEntity = deviceService.getHistoricalImei(sensorTransmissionDataDto.getImei());

		// 生成包含所有时间点的列表
		List<LocalDateTime> timePoints = new ArrayList<>();
		LocalDateTime currentTime = createTime[0];

		// 匹配查询结果中的数据与时间点列表，并将结果加入新的列表中
		List<SensorTransmissionData> resultList = new ArrayList<>();

		if (sensorTransmissionDataDto.getRange().equals("RealTime")) {
			// 对结果列表进行分页处理
			int startIndex = ((int) page.getCurrent() - 1) * (int) page.getSize(); // 计算起始索引
			int endIndex = Math.min(startIndex + (int) page.getSize(), result.size()); // 计算结束索引
			List<SensorTransmissionData> subList = result.subList(startIndex, endIndex); // 获取分页后的数据
			for (SensorTransmissionData transmissionData : subList) {
				transmissionData.setDeviceType(deviceEntity.getDeviceTypeName());
				transmissionData.setDeviceModelName(deviceEntity.getDeviceModelName());
				transmissionData.setImei(deviceEntity.getImei());
			}
			page.setRecords(subList);
			page.setTotal(totalCount);
			return page;
		} else if (sensorTransmissionDataDto.getRange().equals("HourlyAvg")) {
			while (currentTime.isBefore(createTime[1])) {
				timePoints.add(currentTime);
				currentTime = currentTime.plusHours(1);
			}
			resultList = historicalDataService.hourlyAvg(timePoints, result, resultList);
		} else if (sensorTransmissionDataDto.getRange().equals("DailyAvg")) {
			while (currentTime.isBefore(createTime[1])) {
				timePoints.add(currentTime);
				currentTime = currentTime.plusDays(1);
			}
			resultList = historicalDataService.dailyAvg(timePoints, result, resultList);
		}

		List<SensorTransmissionData> subList = getHistoricalPage(page, resultList, deviceEntity);

		page.setRecords(subList); // 设置分页后的数据
		page.setTotal(resultList.size()); // 设置总记录数
		return page;
	}

	private List<SensorTransmissionData> getHistoricalPage(Page page, List<SensorTransmissionData> result, BasicDeviceEntity deviceEntity) {
		// 对结果列表进行分页处理
		int startIndex = ((int) page.getCurrent() - 1) * (int) page.getSize(); // 计算起始索引
		int endIndex = Math.min(startIndex + (int) page.getSize(), result.size()); // 计算结束索引
		List<SensorTransmissionData> subList = result.subList(startIndex, endIndex); // 获取分页后的数据
		for (SensorTransmissionData transmissionData : subList) {
			transmissionData.setDeviceType(deviceEntity.getDeviceTypeName());
			transmissionData.setDeviceModelName(deviceEntity.getDeviceModelName());
			transmissionData.setImei(deviceEntity.getImei());
		}
		return subList;
	}

}